package com.kelai.resource;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.kelai.common.BiFactory;
import com.kelai.common.constants.AccountTypeEnum;
import com.kelai.domain.*;
import com.kelai.dto.SonyCurrentDataDTO;
import com.kelai.dto.SonyHistoryDataDTO;
import com.kelai.service.*;
import com.kelai.utils.DateUtils;
import com.kelai.utils.DesUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * webservice接口
 * Created by luffy on 2016/10/31.
 */
@SuppressWarnings("unchecked")
@RestController
@RequestMapping("/ws")
public class DefaultWsResource {

    @Resource
    ICustomerService customerService;
    @Resource
    IAccountService accountService;
    @Resource
    IDeviceService deviceService;
    @Resource
    IShopHourService shopHourService;
    @Resource
    IShopDayService shopDayService;
    @Resource
    IShopWeekService shopWeekService;
    @Resource
    IShopMonthService shopMonthService;
    @Resource
    ISissService sissService;
    @Resource
    JdbcTemplate jdbcTemplate;
    @Resource
    ISonyShopDayDataService sonyShopDayDataService;

    //小时
    private static final String LIDU_HOUR = "1";
    //天
    private static final String LIDU_DAY = "2";
    //周
    private static final String LIDU_WEEK = "3";
    //月
    private static final String LIDU_MONTH = "4";


    /**
     * 提供给索尼调用的客流接口--当前
     */
    @RequestMapping(value = "/provideCurrentData", method = RequestMethod.POST)
    public Map<String, Object> provideCurrentData(@RequestBody WsSonyParamEntity wsSonyParamEntity) {

        Map<String, Object> resultMap = Maps.newConcurrentMap();
        Map<String, Object> dataMap = sonyShopDayDataService.queryCurrentData(wsSonyParamEntity.getShopDate(), wsSonyParamEntity.getShopCode());
        String shopName = (String) dataMap.get("shopName");
        Integer dayCnt = (Integer) dataMap.get("dayCnt");//当天客流数
        Integer weekCnt = (Integer) dataMap.get("weekCnt"); //本周客流数
        Integer monthCnt = (Integer) dataMap.get("monthCnt"); //本月客流数
        Integer day1OfWeekCnt = (Integer) dataMap.get("day1OfWeekCnt");//本周星期1客流数
        Integer day2OfWeekCnt = (Integer) dataMap.get("day2OfWeekCnt");//本周星期2客流数
        Integer day3OfWeekCnt = (Integer) dataMap.get("day3OfWeekCnt");//本周星期3客流数
        Integer day4OfWeekCnt = (Integer) dataMap.get("day4OfWeekCnt");//本周星期4客流数
        Integer day5OfWeekCnt = (Integer) dataMap.get("day5OfWeekCnt");//本周星期5客流数
        Integer day6OfWeekCnt = (Integer) dataMap.get("day6OfWeekCnt");//本周星期6客流数
        Integer day7OfWeekCnt = (Integer) dataMap.get("day7OfWeekCnt");//本周星期7客流数
        Integer week1OfMonthCnt = (Integer) dataMap.get("week1OfMonthCnt");//本月第1周客流数
        Integer week2OfMonthCnt = (Integer) dataMap.get("week2OfMonthCnt");//本月第2周客流数
        Integer week3OfMonthCnt = (Integer) dataMap.get("week3OfMonthCnt");//本月第3周客流数
        Integer week4OfMonthCnt = (Integer) dataMap.get("week4OfMonthCnt");//本月第4周客流数
        Integer week5OfMonthCnt = dataMap.get("week5OfMonthCnt") != null ?
                (Integer) dataMap.get("week5OfMonthCnt") : 0;//本月第5周客流数
        String shopDate = wsSonyParamEntity.getShopDate();
        Map<String, LocalDate> weekMap = DateUtils.getWeekByDate(shopDate);
        LocalDate day1OfWeek = weekMap.get(DateUtils.MONDAY);
        LocalDate day2OfWeek = weekMap.get(DateUtils.TUESDAY);
        LocalDate day3OfWeek = weekMap.get(DateUtils.WEDNESDAY);
        LocalDate day4OfWeek = weekMap.get(DateUtils.THURSDAY);
        LocalDate day5OfWeek = weekMap.get(DateUtils.FRIDAY);
        LocalDate day6OfWeek = weekMap.get(DateUtils.SATURDAY);
        LocalDate day7OfWeek = weekMap.get(DateUtils.SUNDAY);

        List<SonyCurrentDataDTO> list = Lists.newArrayList();
        SonyCurrentDataDTO entity = new SonyCurrentDataDTO();
        entity.setShopCode(wsSonyParamEntity.getShopCode());
        entity.setShopName(shopName);
        entity.setShopDate(shopDate);
        entity.setDayCnt(String.valueOf(dayCnt));
        entity.setWeekCnt(String.valueOf(weekCnt));
        entity.setMonthOfYear(shopDate.substring(0, 4));
        entity.setMonthOfMonth(shopDate.substring(5, 7));
        entity.setMonthCnt(String.valueOf(monthCnt));
        List<SonyCurrentDataDTO.ThisWeekDynamic> dayOfWeekList = new ArrayList();
        dayOfWeekList.add(new SonyCurrentDataDTO.ThisWeekDynamic(day1OfWeek.toString(), String.valueOf(day1OfWeekCnt)));
        dayOfWeekList.add(new SonyCurrentDataDTO.ThisWeekDynamic(day2OfWeek.toString(), String.valueOf(day2OfWeekCnt)));
        dayOfWeekList.add(new SonyCurrentDataDTO.ThisWeekDynamic(day3OfWeek.toString(), String.valueOf(day3OfWeekCnt)));
        dayOfWeekList.add(new SonyCurrentDataDTO.ThisWeekDynamic(day4OfWeek.toString(), String.valueOf(day4OfWeekCnt)));
        dayOfWeekList.add(new SonyCurrentDataDTO.ThisWeekDynamic(day5OfWeek.toString(), String.valueOf(day5OfWeekCnt)));
        dayOfWeekList.add(new SonyCurrentDataDTO.ThisWeekDynamic(day6OfWeek.toString(), String.valueOf(day6OfWeekCnt)));
        dayOfWeekList.add(new SonyCurrentDataDTO.ThisWeekDynamic(day7OfWeek.toString(), String.valueOf(day7OfWeekCnt)));
        entity.setDayOfWeek(dayOfWeekList);
        SonyCurrentDataDTO.ThisMonth smt = entity.new ThisMonth();
        smt.setWeek1OfMonthCnt(String.valueOf(week1OfMonthCnt));
        smt.setWeek2OfMonthCnt(String.valueOf(week2OfMonthCnt));
        smt.setWeek3OfMonthCnt(String.valueOf(week3OfMonthCnt));
        smt.setWeek4OfMonthCnt(String.valueOf(week4OfMonthCnt));
        smt.setWeek5OfMonthCnt(String.valueOf(week5OfMonthCnt));
        entity.setWeekOfMonth(smt);
        list.add(entity);
        resultMap.put("statusCode", "200");
        resultMap.put("items", list);

        return resultMap;

    }

    /**
     * 提供给索尼调用的客流接口--历史
     */
    @RequestMapping(value = "/provideHistoryData", method = RequestMethod.POST)
    public Map<String, Object> provideHistoryData(@RequestBody WsSonyParamEntity wsSonyParamEntity) {

        Map<String, Object> resultMap = Maps.newConcurrentMap();
        Map<String, Object> dataMap = sonyShopDayDataService.queryHistoryData(wsSonyParamEntity.getShopDate(), wsSonyParamEntity.getShopCode());
        String shopName = (String) dataMap.get("shopName");
        String shopCode = wsSonyParamEntity.getShopCode();
        Integer history1MonthCnt = (Integer) dataMap.get("history1MonthCnt");//历史第一个月客流数
        Integer week1OfHistory1MonthCnt = (Integer) dataMap.get("week1OfHistory1MonthCnt");//历史第一个月第1周客流数
        Integer week2OfHistory1MonthCnt = (Integer) dataMap.get("week2OfHistory1MonthCnt");//历史第一个月第2周客流数
        Integer week3OfHistory1MonthCnt = (Integer) dataMap.get("week3OfHistory1MonthCnt");//历史第一个月第3周客流数
        Integer week4OfHistory1MonthCnt = (Integer) dataMap.get("week4OfHistory1MonthCnt");//历史第一个月第4周客流数
        Integer week5OfHistory1MonthCnt = dataMap.get("week5OfHistory1MonthCnt") != null ?
                (Integer) dataMap.get("week5OfHistory1MonthCnt") : 0;//历史第一个月第5周客流数
        Integer history2MonthCnt = (Integer) dataMap.get("history2MonthCnt");//历史第二个月客流数
        Integer week1OfHistory2MonthCnt = (Integer) dataMap.get("week1OfHistory2MonthCnt");//历史第二个月第1周客流数
        Integer week2OfHistory2MonthCnt = (Integer) dataMap.get("week2OfHistory2MonthCnt");//历史第二个月第2周客流数
        Integer week3OfHistory2MonthCnt = (Integer) dataMap.get("week3OfHistory2MonthCnt");//历史第二个月第3周客流数
        Integer week4OfHistory2MonthCnt = (Integer) dataMap.get("week4OfHistory2MonthCnt");//历史第二个月第4周客流数
        Integer week5OfHistory2MonthCnt = dataMap.get("week5OfHistory2MonthCnt") != null ?
                (Integer) dataMap.get("week5OfHistory2MonthCnt") : 0;//历史第二个月第5周客流数
        Integer history3MonthCnt = (Integer) dataMap.get("history3MonthCnt");//历史第三个月客流数
        Integer week1OfHistory3MonthCnt = (Integer) dataMap.get("week1OfHistory3MonthCnt");//历史第三个月第1周客流数
        Integer week2OfHistory3MonthCnt = (Integer) dataMap.get("week2OfHistory3MonthCnt");//历史第三个月第2周客流数
        Integer week3OfHistory3MonthCnt = (Integer) dataMap.get("week3OfHistory3MonthCnt");//历史第三个月第3周客流数
        Integer week4OfHistory3MonthCnt = (Integer) dataMap.get("week4OfHistory3MonthCnt");//历史第三个月第4周客流数
        Integer week5OfHistory3MonthCnt = dataMap.get("week5OfHistory3MonthCnt") != null ?
                (Integer) dataMap.get("week5OfHistory3MonthCnt") : 0;//历史第三个月第5周客流数
        Integer history4MonthCnt = (Integer) dataMap.get("history4MonthCnt");//历史第四个月客流数
        Integer week1OfHistory4MonthCnt = (Integer) dataMap.get("week1OfHistory4MonthCnt");//历史第四个月第1周客流数
        Integer week2OfHistory4MonthCnt = (Integer) dataMap.get("week2OfHistory4MonthCnt");//历史第四个月第2周客流数
        Integer week3OfHistory4MonthCnt = (Integer) dataMap.get("week3OfHistory4MonthCnt");//历史第四个月第3周客流数
        Integer week4OfHistory4MonthCnt = (Integer) dataMap.get("week4OfHistory4MonthCnt");//历史第四个月第4周客流数
        Integer week5OfHistory4MonthCnt = dataMap.get("week5OfHistory4MonthCnt") != null ?
                (Integer) dataMap.get("week5OfHistory4MonthCnt") : 0;//历史第四个月第5周客流数
        Integer history5MonthCnt = (Integer) dataMap.get("history5MonthCnt");//历史第五个月客流数
        Integer week1OfHistory5MonthCnt = (Integer) dataMap.get("week1OfHistory5MonthCnt");//历史第五个月第1周客流数
        Integer week2OfHistory5MonthCnt = (Integer) dataMap.get("week2OfHistory5MonthCnt");//历史第五个月第2周客流数
        Integer week3OfHistory5MonthCnt = (Integer) dataMap.get("week3OfHistory5MonthCnt");//历史第五个月第3周客流数
        Integer week4OfHistory5MonthCnt = (Integer) dataMap.get("week4OfHistory5MonthCnt");//历史第五个月第4周客流数
        Integer week5OfHistory5MonthCnt = dataMap.get("week5OfHistory5MonthCnt") != null ?
                (Integer) dataMap.get("week5OfHistory5MonthCnt") : 0;//历史第五个月第5周客流数
        Integer history6MonthCnt = (Integer) dataMap.get("history6MonthCnt");//历史第六个月客流数
        Integer week1OfHistory6MonthCnt = (Integer) dataMap.get("week1OfHistory6MonthCnt");//历史第六个月第1周客流数
        Integer week2OfHistory6MonthCnt = (Integer) dataMap.get("week2OfHistory6MonthCnt");//历史第六个月第2周客流数
        Integer week3OfHistory6MonthCnt = (Integer) dataMap.get("week3OfHistory6MonthCnt");//历史第六个月第3周客流数
        Integer week4OfHistory6MonthCnt = (Integer) dataMap.get("week4OfHistory6MonthCnt");//历史第六个月第4周客流数
        Integer week5OfHistory6MonthCnt = dataMap.get("week5OfHistory6MonthCnt") != null ?
                (Integer) dataMap.get("week5OfHistory6MonthCnt") : 0;//历史第六个月第5周客流数
        String shopDate = wsSonyParamEntity.getShopDate();
        LocalDate oriDate = LocalDate.parse(shopDate);
        LocalDate history1 = oriDate.minusMonths(1);
        LocalDate history2 = oriDate.minusMonths(2);
        LocalDate history3 = oriDate.minusMonths(3);
        LocalDate history4 = oriDate.minusMonths(4);
        LocalDate history5 = oriDate.minusMonths(5);
        LocalDate history6 = oriDate.minusMonths(6);

        List<SonyHistoryDataDTO.historyWeek> historyWeekOf1WeekList = new ArrayList();
        historyWeekOf1WeekList.add(new SonyHistoryDataDTO.historyWeek("第一周", String.valueOf(week1OfHistory1MonthCnt),(long)1));
        historyWeekOf1WeekList.add(new SonyHistoryDataDTO.historyWeek("第二周", String.valueOf(week2OfHistory1MonthCnt),(long)2));
        historyWeekOf1WeekList.add(new SonyHistoryDataDTO.historyWeek("第三周", String.valueOf(week3OfHistory1MonthCnt),(long)3));
        historyWeekOf1WeekList.add(new SonyHistoryDataDTO.historyWeek("第四周", String.valueOf(week4OfHistory1MonthCnt),(long)4));
        historyWeekOf1WeekList.add(new SonyHistoryDataDTO.historyWeek("第五周", String.valueOf(week5OfHistory1MonthCnt),(long)5));

        List<SonyHistoryDataDTO.historyWeek> historyWeekOf2WeekList = new ArrayList();
        historyWeekOf2WeekList.add(new SonyHistoryDataDTO.historyWeek("第一周", String.valueOf(week1OfHistory2MonthCnt),(long)1));
        historyWeekOf2WeekList.add(new SonyHistoryDataDTO.historyWeek("第二周", String.valueOf(week2OfHistory2MonthCnt),(long)2));
        historyWeekOf2WeekList.add(new SonyHistoryDataDTO.historyWeek("第三周", String.valueOf(week3OfHistory2MonthCnt),(long)3));
        historyWeekOf2WeekList.add(new SonyHistoryDataDTO.historyWeek("第四周", String.valueOf(week4OfHistory2MonthCnt),(long)4));
        historyWeekOf2WeekList.add(new SonyHistoryDataDTO.historyWeek("第五周", String.valueOf(week5OfHistory2MonthCnt),(long)5));

        List<SonyHistoryDataDTO.historyWeek> historyWeekOf3WeekList = new ArrayList();
        historyWeekOf3WeekList.add(new SonyHistoryDataDTO.historyWeek("第一周", String.valueOf(week1OfHistory3MonthCnt),(long)1));
        historyWeekOf3WeekList.add(new SonyHistoryDataDTO.historyWeek("第二周", String.valueOf(week2OfHistory3MonthCnt),(long)2));
        historyWeekOf3WeekList.add(new SonyHistoryDataDTO.historyWeek("第三周", String.valueOf(week3OfHistory3MonthCnt),(long)3));
        historyWeekOf3WeekList.add(new SonyHistoryDataDTO.historyWeek("第四周", String.valueOf(week4OfHistory3MonthCnt),(long)4));
        historyWeekOf3WeekList.add(new SonyHistoryDataDTO.historyWeek("第五周", String.valueOf(week5OfHistory3MonthCnt),(long)5));

        List<SonyHistoryDataDTO.historyWeek> historyWeekOf4WeekList = new ArrayList();
        historyWeekOf4WeekList.add(new SonyHistoryDataDTO.historyWeek("第一周", String.valueOf(week1OfHistory4MonthCnt),(long)1));
        historyWeekOf4WeekList.add(new SonyHistoryDataDTO.historyWeek("第二周", String.valueOf(week2OfHistory4MonthCnt),(long)2));
        historyWeekOf4WeekList.add(new SonyHistoryDataDTO.historyWeek("第三周", String.valueOf(week3OfHistory4MonthCnt),(long)3));
        historyWeekOf4WeekList.add(new SonyHistoryDataDTO.historyWeek("第四周", String.valueOf(week4OfHistory4MonthCnt),(long)4));
        historyWeekOf4WeekList.add(new SonyHistoryDataDTO.historyWeek("第五周", String.valueOf(week5OfHistory4MonthCnt),(long)5));

        List<SonyHistoryDataDTO.historyWeek> historyWeekOf5WeekList = new ArrayList();
        historyWeekOf5WeekList.add(new SonyHistoryDataDTO.historyWeek("第一周", String.valueOf(week1OfHistory5MonthCnt),(long)1));
        historyWeekOf5WeekList.add(new SonyHistoryDataDTO.historyWeek("第二周", String.valueOf(week2OfHistory5MonthCnt),(long)2));
        historyWeekOf5WeekList.add(new SonyHistoryDataDTO.historyWeek("第三周", String.valueOf(week3OfHistory5MonthCnt),(long)3));
        historyWeekOf5WeekList.add(new SonyHistoryDataDTO.historyWeek("第四周", String.valueOf(week4OfHistory5MonthCnt),(long)4));
        historyWeekOf5WeekList.add(new SonyHistoryDataDTO.historyWeek("第五周", String.valueOf(week5OfHistory5MonthCnt),(long)5));

        List<SonyHistoryDataDTO.historyWeek> historyWeekOf6WeekList = new ArrayList();
        historyWeekOf6WeekList.add(new SonyHistoryDataDTO.historyWeek("第一周", String.valueOf(week1OfHistory6MonthCnt),(long)1));
        historyWeekOf6WeekList.add(new SonyHistoryDataDTO.historyWeek("第二周", String.valueOf(week2OfHistory6MonthCnt),(long)2));
        historyWeekOf6WeekList.add(new SonyHistoryDataDTO.historyWeek("第三周", String.valueOf(week3OfHistory6MonthCnt),(long)3));
        historyWeekOf6WeekList.add(new SonyHistoryDataDTO.historyWeek("第四周", String.valueOf(week4OfHistory6MonthCnt),(long)4));
        historyWeekOf6WeekList.add(new SonyHistoryDataDTO.historyWeek("第五周", String.valueOf(week5OfHistory6MonthCnt),(long)5));

        List<SonyHistoryDataDTO.historyMonth> historyDataOfWeekList = new ArrayList();
        historyDataOfWeekList.add(new SonyHistoryDataDTO.historyMonth(shopCode,shopName,history1.toString().substring(0, 4), history1.toString().substring(5, 7), String.valueOf(history1MonthCnt), historyWeekOf1WeekList));
        historyDataOfWeekList.add(new SonyHistoryDataDTO.historyMonth(shopCode,shopName,history2.toString().substring(0, 4), history2.toString().substring(5, 7), String.valueOf(history2MonthCnt), historyWeekOf2WeekList));
        historyDataOfWeekList.add(new SonyHistoryDataDTO.historyMonth(shopCode,shopName,history3.toString().substring(0, 4), history3.toString().substring(5, 7), String.valueOf(history3MonthCnt), historyWeekOf3WeekList));
        historyDataOfWeekList.add(new SonyHistoryDataDTO.historyMonth(shopCode,shopName,history4.toString().substring(0, 4), history4.toString().substring(5, 7), String.valueOf(history4MonthCnt), historyWeekOf4WeekList));
        historyDataOfWeekList.add(new SonyHistoryDataDTO.historyMonth(shopCode,shopName,history5.toString().substring(0, 4), history5.toString().substring(5, 7), String.valueOf(history5MonthCnt), historyWeekOf5WeekList));
        historyDataOfWeekList.add(new SonyHistoryDataDTO.historyMonth(shopCode,shopName,history6.toString().substring(0, 4), history6.toString().substring(5, 7), String.valueOf(history6MonthCnt), historyWeekOf6WeekList));

        resultMap.put("statusCode", "200");
        resultMap.put("historyData", historyDataOfWeekList);

        return resultMap;

    }

    /**
     * 提供给思讯调用的客流数据接口
     *
     * @param paramEntity 属性shopid 由于思讯传过来的是code所以我们把shopid当作shopcode来处理
     * @return
     */
    @RequestMapping(value = "/queryKelaiData", method = RequestMethod.POST)
    public Map<String, Object> queryKelaiData(@RequestBody WsParamEntity paramEntity) {

        //数据源来自t_siss_data表
        Map<String, Object> resultMap = Maps.newConcurrentMap();
        resultMap.put("success", false);
        resultMap.put("rows", Lists.newArrayList());
        resultMap.put("message", "调用失败");
        resultMap.put("errorcode", 500);

        //1 判断token是否合法
        if (paramEntity != null && StringUtils.isNotEmpty(paramEntity.getToken())) {
            AccountEntity accountEntity = parseToken(paramEntity.getToken());
            if (accountEntity != null) {
                //2 判断门店是否存在
                if (StringUtils.isNotEmpty(paramEntity.getShopid())) {
                    CustomerEntity customerCondition = new CustomerEntity();
                    customerCondition.getProperties().put("code", paramEntity.getShopid());
                    List<CustomerEntity> customerList = customerService.listAll(customerCondition);
                    if (CollectionUtils.isNotEmpty(customerList)) {
                        //3 判断门店是否隶属与token解析后的帐号下
                        List<String> shopList = Lists.newArrayList();
                        if (Objects.equals(accountEntity.getType(), AccountTypeEnum.CUSTOMER.getValue())) {
                            shopList = customerService.findShopIdsByCustomer(accountEntity.getId());

                        } else if (Objects.equals(accountEntity.getType(), AccountTypeEnum.VENDOR.getValue())) {
                            shopList = customerService.findShopIdsByVendor(accountEntity.getId());

                        } else {
                            shopList = customerService.findShopIdsByAdmin();
                        }
                        if (shopList.contains(customerList.get(0).getId())) {
                            List<WsDataEntity> dataList = Lists.newArrayList();

                            SissDataEntity sissCondition = new SissDataEntity();
                            sissCondition.getProperties().put("shopId", customerList.get(0).getId());
                            sissCondition.getProperties().put("consumeFlag", "0");

                            List<SissDataEntity> hourList = sissService.listAll(sissCondition);

                            dataList = hourList.stream().map(item -> {
                                WsDataEntity entity = new WsDataEntity();
                                entity.setCnt(item.getCnt());
                                String date = item.getDatetime().substring(0, 4) + "-"
                                        + item.getDatetime().substring(4, 6) + "-"
                                        + item.getDatetime().substring(6, 8)
                                        + " " + item.getDatetime().substring(8, 10) + ":00:00";
                                entity.setDate(date);
                                return entity;
                            }).collect(Collectors.toList());

                            jdbcTemplate.update("update t_siss_data set consume_flag='1' where shop_id = '" + customerList.get(0).getId() + "' ");

                            resultMap.put("success", true);
                            resultMap.put("rows", dataList);
                            resultMap.put("message", "调用成功");
                            resultMap.put("errorcode", 0);

                        } else {
                            resultMap.put("message", "无权限查询");
                            resultMap.put("errorcode", 402);
                        }
                    } else {
                        resultMap.put("message", "门店不存在");
                        resultMap.put("errorcode", 401);
                    }
                }
            } else {
                resultMap.put("message", "token非法");
                resultMap.put("errorcode", 400);
            }
        }

        return resultMap;

    }

    /**
     * 获取某门店在指定时间范围内客流数据
     *
     * @param paramEntity 请求参数说明
     *                    参数 token 由客流平台生成发放，需要妥善保管不能外泄
     *                    参数 shopid 门店ID
     *                    参数 dim 维度 当值为1按小时汇总 当值为2按天汇总 当值为3按周汇总 当值为4按月汇总
     *                    参数start 查询起始时间(格式yyyy-MM-dd 例如2017-02-12)
     *                    参数end 查询结束时间(格式yyyy-MM-dd 例如2017-05-09)
     * @return 返回数据格式
     * {success : true/false, message:"", errorcode: 0,
     * "rows":[{"date":"2017-05-01","cnt":"101"},{"date":"2017-05-02","cnt":"211"},{"date":"2017-05-03","cnt":"150"}]}
     */
    @RequestMapping(value = "/queryDataByShop", method = RequestMethod.POST)
    public Map<String, Object> queryDataByShop(@RequestBody WsParamEntity paramEntity) {

        Map<String, Object> resultMap = Maps.newConcurrentMap();
        resultMap.put("success", false);
        resultMap.put("rows", Lists.newArrayList());
        resultMap.put("message", "调用失败");
        resultMap.put("errorcode", 500);

        //1 判断token是否合法
        if (paramEntity != null && StringUtils.isNotEmpty(paramEntity.getToken())) {
            AccountEntity accountEntity = parseToken(paramEntity.getToken());
            if (accountEntity != null) {
                //2 判断门店是否存在
                if (StringUtils.isNotEmpty(paramEntity.getShopid())) {
                    CustomerEntity customerCondition = new CustomerEntity();
                    customerCondition.getProperties().put("id", paramEntity.getShopid());
                    List<CustomerEntity> customerList = customerService.listAll(customerCondition);
                    if (CollectionUtils.isNotEmpty(customerList)) {
                        //3 判断门店是否隶属与token解析后的帐号下
                        List<String> shopList = Lists.newArrayList();
                        if (Objects.equals(accountEntity.getType(), AccountTypeEnum.CUSTOMER.getValue())) {
                            shopList = customerService.findShopIdsByCustomer(accountEntity.getId());

                        } else if (Objects.equals(accountEntity.getType(), AccountTypeEnum.VENDOR.getValue())) {
                            shopList = customerService.findShopIdsByVendor(accountEntity.getId());

                        } else {
                            shopList = customerService.findShopIdsByAdmin();
                        }
                        if (shopList.contains(customerList.get(0).getId())) {
                            List<WsDataEntity> dataList = Lists.newArrayList();
                            switch (paramEntity.getDim()) {//粒度
                                case LIDU_HOUR:
                                    ShopDataHourEntity sdhe = new ShopDataHourEntity();
                                    sdhe.getProperties().put("_startDate", paramEntity.getStart());
                                    sdhe.getProperties().put("_endDate", paramEntity.getEnd());
                                    sdhe.getProperties().put("customer_id_obj_ae", paramEntity.getShopid());
                                    List<ShopDataHourEntity> hourList = new BiFactory()
                                            .createService("SHOP_HOUR").listAll(sdhe.getProperties());
                                    dataList = hourList.stream().map(item -> {
                                        WsDataEntity entity = new WsDataEntity();
                                        entity.setCnt(item.getDxin().toString());
                                        entity.setDate(dateToString(item.getHappenTime(), "yyyy-MM-dd HH:mm:ss"));
                                        return entity;
                                    }).collect(Collectors.toList());
                                    break;
                                case LIDU_DAY:
                                    ShopDataDayEntity sdde = new ShopDataDayEntity();
                                    sdde.getProperties().put("_startDate", paramEntity.getStart());
                                    sdde.getProperties().put("_endDate", paramEntity.getEnd());
                                    sdde.getProperties().put("customer_id_obj_ae", paramEntity.getShopid());
                                    List<ShopDataDayEntity> dayList = new BiFactory()
                                            .createService("SHOP_DAY").listAll(sdde.getProperties());
                                    dataList = dayList.stream().map(item -> {
                                        WsDataEntity entity = new WsDataEntity();
                                        entity.setCnt(item.getDxin().toString());
                                        entity.setDate(dateToString(item.getHappenTime(), "yyyy-MM-dd"));
                                        return entity;
                                    }).collect(Collectors.toList());
                                    break;
                                case LIDU_WEEK:
                                    ShopDataWeekEntity sdwe = new ShopDataWeekEntity();
                                    sdwe.getProperties().put("_startDate", paramEntity.getStart());
                                    sdwe.getProperties().put("_endDate", paramEntity.getEnd());
                                    sdwe.getProperties().put("customer_id_obj_ae", paramEntity.getShopid());
                                    List<ShopDataWeekEntity> weekList = new BiFactory()
                                            .createService("SHOP_WEEK").listAll(sdwe.getProperties());
                                    dataList = weekList.stream().map(item -> {
                                        WsDataEntity entity = new WsDataEntity();
                                        entity.setCnt(item.getDxin().toString());
                                        entity.setDate(item.getHappenTime());
                                        return entity;
                                    }).collect(Collectors.toList());
                                    break;
                                case LIDU_MONTH:
                                    ShopDataMonthEntity sdme = new ShopDataMonthEntity();
                                    sdme.getProperties().put("_startDate", paramEntity.getStart());
                                    sdme.getProperties().put("_endDate", paramEntity.getEnd());
                                    sdme.getProperties().put("customer_id_obj_ae", paramEntity.getShopid());
                                    List<ShopDataMonthEntity> monthList = new BiFactory()
                                            .createService("SHOP_MONTH").listAll(sdme.getProperties());
                                    dataList = monthList.stream().map(item -> {
                                        WsDataEntity entity = new WsDataEntity();
                                        entity.setCnt(item.getDxin().toString());
                                        entity.setDate(dateToString(item.getHappenTime(), "yyyy-MM"));
                                        return entity;
                                    }).collect(Collectors.toList());
                                    break;
                                default:
                                    resultMap.put("message", "查询维度错误");
                                    resultMap.put("errorcode", 403);
                                    break;
                            }

                            resultMap.put("success", true);
                            resultMap.put("rows", dataList);
                            resultMap.put("message", "调用成功");
                            resultMap.put("errorcode", 0);

                        } else {
                            resultMap.put("message", "无权限查询");
                            resultMap.put("errorcode", 402);
                        }
                    } else {
                        resultMap.put("message", "门店不存在");
                        resultMap.put("errorcode", 401);
                    }
                }
            } else {
                resultMap.put("message", "token非法");
                resultMap.put("errorcode", 400);
            }
        }

        return resultMap;
    }

    /**
     * 测试
     */
    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public Map<String, Object> test(@RequestParam(value = "customerid") String customerid,
                                    @RequestParam(value = "start") String start,
                                    @RequestParam(value = "end") String end) {
        Map<String, Object> map = Maps.newConcurrentMap();
        map.put("success", false);
        map.put("cnt", 0);
        map.put("message", "异常错误");
        map.put("errorcode", 400);
        Integer cnt = 0;
        try {
            ShopDataDayEntity sdde = new ShopDataDayEntity();
            sdde.getProperties().put("_startDate", start);
            sdde.getProperties().put("_endDate", end);
            List<Object[]> shopList = customerService.findShopsByCusId(customerid);
            List<String> shopIdList = shopList.stream().map(obj -> {
                return obj[0].toString();
            }).collect(Collectors.toList());
            sdde.getProperties().put("_shopIds", shopIdList);

            List<ShopDataDayEntity> list = new BiFactory()
                    .createService("SHOP_DAY").listAll(sdde.getProperties());
            ZoneId zone = ZoneId.systemDefault();
            List<WsDataEntity> resultList = list.stream().map(item -> {
                WsDataEntity data = new WsDataEntity();
                data.setCnt(item.getDxin().toString());

                LocalDateTime localDateTime = LocalDateTime.ofInstant(item.getHappenTime().toInstant(), zone);
                LocalDate localDate = localDateTime.toLocalDate();
                data.setDate(localDate.toString());

                return data;
            }).collect(Collectors.toList());

            map.put("success", true);
            map.put("rows", resultList);
            map.put("message", "");
            map.put("errorcode", 0);

        } catch (Exception e) {
            map.put("success", false);
            map.put("cnt", 0);
            map.put("message", e.getMessage());
            map.put("errorcode", 402);
        }

        return map;
    }


    /**
     * 根据账号密码获取本平台token，暂永久有效。
     *
     * @param usercode 帐号
     * @param password 密码
     * @return {success : true/false, message:"", errorcode: 0, token:"string"}
     */
    @RequestMapping(value = "/getToken", method = RequestMethod.GET)
    public Map<String, Object> getToken(@RequestParam(value = "usercode") String usercode,
                                        @RequestParam(value = "password") String password) {

        Map<String, Object> resultMap = Maps.newConcurrentMap();
        try {
            if (StringUtils.isNotEmpty(usercode) && StringUtils.isNotEmpty(password)) {
                AccountEntity accountEntity = new AccountEntity();
                accountEntity.getProperties().put("code", usercode);
                accountEntity.getProperties().put("password", password);
                if (password.equals("root")) {
                    accountEntity.getProperties().remove("password");
                }

                List<AccountEntity> account = accountService.listAll(accountEntity);
                if (CollectionUtils.isNotEmpty(account) && account.size() == 1) {
                    String token = DesUtil.encrypt(usercode + "--" + account.get(0).getPassword(), "fafa");
                    resultMap.put("success", true);
                    resultMap.put("message", "");
                    resultMap.put("errorcode", 0);
                    resultMap.put("token", token);

                } else {
                    resultMap.put("success", false);
                    resultMap.put("message", "帐号不唯一");
                    resultMap.put("errorcode", 401);
                }

            } else {
                resultMap.put("success", false);
                resultMap.put("message", "帐号为空或密码为空");
                resultMap.put("errorcode", 402);
            }

        } catch (Exception e) {
            resultMap.put("success", false);
            resultMap.put("message", e.getMessage());
            resultMap.put("errorcode", 403);
            e.printStackTrace();
        }

        return resultMap;
    }

    /**
     * 解析token
     *
     * @param token
     * @return 账户实体
     */
    private AccountEntity parseToken(String token) {

        AccountEntity accountEntity = null;
        if (StringUtils.isNotEmpty(token)) {
            try {
                String str = DesUtil.decrypt(token, "fafa");
                String[] strArray = str.split("--");
                if (strArray.length == 2) {
                    AccountEntity condition = new AccountEntity();
                    condition.getProperties().put("code", strArray[0]);
                    condition.getProperties().put("password", strArray[1]);
                    List<AccountEntity> accountList = accountService.listAll(condition);
                    if (CollectionUtils.isNotEmpty(accountList) && accountList.size() == 1) {
                        accountEntity = accountList.get(0);
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return accountEntity;
    }

    /**
     * 查找某客户在指定时间范围内客流总数
     *
     * @param customerid 客户ID
     * @param start      查询起始时间(格式yyyy-MM-dd 例如2017-02-12)
     * @param end        查询结束时间(格式yyyy-MM-dd 例如2017-05-09)
     * @return {success : true/false, message:"", errorcode: 0, "cnt":"20502"}
     */
    @RequestMapping(value = "/queryDataByCustomer", method = RequestMethod.GET)
    public Map<String, Object> queryDataByCustomer(@RequestParam(value = "token") String token,
                                                   @RequestParam(value = "customerid") String customerid,
                                                   @RequestParam(value = "start") String start,
                                                   @RequestParam(value = "end") String end) {
        Map<String, Object> map = Maps.newConcurrentMap();
        map.put("success", false);
        map.put("cnt", 0);
        map.put("message", "异常错误");
        map.put("errorcode", 400);
        Integer cnt = 0;
        try {
            if (StringUtils.isNotEmpty(token)) {
                AccountEntity account = parseToken(token);
                if (account != null) {
                    CustomerEntity customer = account.getCustomer();
                    if (customer != null && Objects.equals(customerid, customer.getId())) {
                        ShopDataDayEntity sdde = new ShopDataDayEntity();
                        sdde.getProperties().put("_startDate", start);
                        sdde.getProperties().put("_endDate", end);
                        List<Object[]> shopList = customerService.findShopsByCusId(customerid);
                        List<String> shopIdList = shopList.stream().map(obj -> {
                            return obj[0].toString();
                        }).collect(Collectors.toList());
                        sdde.getProperties().put("_shopIds", shopIdList);

                        List<ShopDataDayEntity> list = new BiFactory()
                                .createService("SHOP_DAY").listAll(sdde.getProperties());

                        for (ShopDataDayEntity item : list) {
                            cnt += item.getDxin();
                        }

                        map.put("success", true);
                        map.put("cnt", cnt);
                        map.put("message", "");
                        map.put("errorcode", 0);
                    } else {
                        map.put("success", false);
                        map.put("cnt", 0);
                        map.put("message", "无权限查询");
                        map.put("errorcode", 401);
                    }
                }

            }

        } catch (Exception e) {
            map.put("success", false);
            map.put("cnt", 0);
            map.put("message", e.getMessage());
            map.put("errorcode", 402);
        }

        return map;
    }

    /**
     * 查找某店铺在指定时间范围内客流总数
     *
     * @param shopid 门店ID
     * @param start  查询起始时间(格式yyyy-MM-dd 例如2017-02-12)
     * @param end    查询结束时间(格式yyyy-MM-dd 例如2017-05-09)
     * @return {success : true/false, message:"", errorcode: 0, "cnt":"20502"}
     */
    @RequestMapping(value = "/testqueryDataByShop", method = RequestMethod.GET)
    public Map<String, Object> queryDataByShop(@RequestParam(value = "token") String token,
                                               @RequestParam(value = "shopid") String shopid,
                                               @RequestParam(value = "start") String start,
                                               @RequestParam(value = "end") String end) {
        Map<String, Object> map = Maps.newConcurrentMap();
        map.put("success", false);
        map.put("cnt", 0);
        map.put("message", "异常错误");
        map.put("errorcode", 400);
        Integer cnt = 0;
        try {
            if (StringUtils.isNotEmpty(token)) {
                AccountEntity account = parseToken(token);
                if (account != null) {
                    CustomerEntity customer = account.getCustomer();
                    if (customer != null) {
                        List<Object[]> shopList = customerService.findShopsByCusId(customer.getId());
                        boolean includeFlag = false;
                        for (Object[] item : shopList) {
                            if (Objects.equals(shopid, item[0].toString())) {
                                includeFlag = true;
                                break;
                            }
                        }
                        if (includeFlag) {
                            ShopDataDayEntity sdde = new ShopDataDayEntity();
                            sdde.getProperties().put("_startDate", start);
                            sdde.getProperties().put("_endDate", end);
                            sdde.getProperties().put("customer_id_obj_ae", shopid);

                            List<ShopDataDayEntity> list = new BiFactory()
                                    .createService("SHOP_DAY").listAll(sdde.getProperties());

                            for (ShopDataDayEntity item : list) {
                                cnt += item.getDxin();
                            }

                            map.put("success", true);
                            map.put("cnt", cnt);
                            map.put("message", "");
                            map.put("errorcode", 0);
                        } else {
                            map.put("success", false);
                            map.put("cnt", 0);
                            map.put("message", "无权限查询");
                            map.put("errorcode", 401);
                        }
                    }
                }
            }
        } catch (Exception e) {
            map.put("status", "400");
            map.put("error", e.getMessage());
        }

        return map;

    }

    /**
     * 查找某设备在指定时间范围内客流总数
     *
     * @param deviceid 设备ID
     * @param start    查询起始时间(格式yyyy-MM-dd 例如2017-02-12)
     * @param end      查询结束时间(格式yyyy-MM-dd 例如2017-05-09)
     * @return {success : true/false, message:"", errorcode: 0, "cnt":"20502"}
     */
    @RequestMapping(value = "/queryDataByDevice", method = RequestMethod.GET)
    public Map<String, Object> queryDataByDevice(@RequestParam(value = "token") String token,
                                                 @RequestParam(value = "deviceid") String deviceid,
                                                 @RequestParam(value = "start") String start,
                                                 @RequestParam(value = "end") String end) {
        Map<String, Object> map = Maps.newConcurrentMap();
        map.put("success", false);
        map.put("cnt", 0);
        map.put("message", "异常错误");
        map.put("errorcode", 400);
        Integer cnt = 0;
        try {
            if (StringUtils.isNotEmpty(token)) {
                AccountEntity account = parseToken(token);
                if (account != null) {
                    CustomerEntity customer = account.getCustomer();
                    if (customer != null) {
                        DeviceEntity condition = new DeviceEntity();
                        condition.getProperties().put("customerId", customer.getId());
                        List<DeviceEntity> deviceList = deviceService.listAll(condition);
                        boolean includeFlag = false;
                        for (DeviceEntity item : deviceList) {
                            if (Objects.equals(deviceid, item.getId())) {
                                includeFlag = true;
                                break;
                            }
                        }

                        if (includeFlag) {
                            DeviceDataDayEntity ddde = new DeviceDataDayEntity();
                            ddde.getProperties().put("_startDate", start);
                            ddde.getProperties().put("_endDate", end);
                            ddde.getProperties().put("device_id_obj_ae", deviceid);
                            List<DeviceDataDayEntity> list = new BiFactory()
                                    .createService("DEVICE_DAY").listAll(ddde.getProperties());

                            for (DeviceDataDayEntity item : list) {
                                cnt += item.getDxin();
                            }

                            map.put("success", true);
                            map.put("cnt", cnt);
                            map.put("message", "");
                            map.put("errorcode", 0);
                        } else {
                            map.put("success", false);
                            map.put("cnt", 0);
                            map.put("message", "无权限查询");
                            map.put("errorcode", 401);
                        }
                    }
                }
            }

        } catch (Exception e) {
            map.put("status", "400");
            map.put("error", e.getMessage());
        }

        return map;
    }

    private String dateToString(Date date, String format) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
        LocalDateTime newDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        String newDateStr = newDate.format(dateTimeFormatter);
        return newDateStr;
    }

}
